package com.pjedu.springbootredis.service.serviceimp;

import com.pjedu.springbootredis.entity.User;
import com.pjedu.springbootredis.mapper.UserMapper;
import com.pjedu.springbootredis.service.UserService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @Author 汪洋
 * @Description
 */
@Service("userService")
public class UserServiceImp implements UserService {
    @Resource
    private UserMapper userMapper;
    @Resource
    private RedisTemplate redisTemplate;
    @Override
    public List<User> findAll(){
        //查询数据之前,先检查缓存中是否存在该数据
        if (redisTemplate.opsForList().size("users")!=0) {
            //返回该数据
            return redisTemplate.opsForList().range("users",0,-1);
        }else{
            //如果缓存中不存在,则需要到数据库里进行获取
            List<User> users = userMapper.selectAll();
            //存储到缓存中去
            redisTemplate.opsForList().rightPushAll("users",users);
            return users;
        }
    }

    @Override
    public User findById(Integer id) {
        //定义一个User对象
        User user = null;
        //获取到缓存中的所有数据
        List<User> users = redisTemplate.opsForList().range("users", 0, -1);
        //进行遍历,并且判断你要查找的数据是否存在
        for (int i = 0; i < users.size(); i++) {
            if (users.get(i).getUid().equals(id)) {
                //如果存在,则取出来
                user = (User)redisTemplate.opsForList().index("users",i);
                //跳出循环
                break;
            }
        }
        //判断user对象是否为null
        if (user != null) {
            return user;
        }else {
            //在缓存中没有,得从数据库里查询
            return userMapper.selectByPrimaryKey(id);
        }
    }

    @Override
    public User login(User user) {//zhangsan 111111
        //首先要在缓存中去寻找登录的用户数据,如果存在,并且用户名密码正确,则直接登录即可
        if(redisTemplate.opsForHash().hasKey("user",user.getUsername())&&
        redisTemplate.opsForHash().get("user",user.getUsername()).equals(user.getPassword())){
            //当前用户在缓存中存在并且用户名密码正确
            return user;
        }else {
            //如果缓存中不存在或者是缓存中的密码不正确,那么需要额外查询数据库
            User dbUser = userMapper.selectOne(user);
            //如果查询到了该用户
            if (dbUser != null) {
                //还需要往session里面存储用户状态,略过
                //把用户数据存储到缓存中
                redisTemplate.opsForHash().put("user",user.getUsername(),user.getPassword());
                //设置缓存中用户数据的租期
                redisTemplate.expire("user", 1, TimeUnit.HOURS);
                return dbUser;
            }
        }
        return null;
    }

    @Override
    public int deleteById(Integer uid) {
        //先把数据从数据库中删除掉
        int number = userMapper.deleteByPrimaryKey(uid);
        //如果number大于0,就证明该数据删除成功
        if (number>0) {
            //此时就需要把数据同步到缓存中去
            List<User> users = redisTemplate.opsForList().range("users", 0, -1);
            for (int i = 0; i < users.size(); i++) {
                if (uid.equals(users.get(i).getUid())){
                    redisTemplate.opsForList().remove("users",1,users.get(i));
                }
            }
        }
        return number;
    }

    @Override
    public int updateUser(User user) {
        //先把数据从数据库中进行修改
        int number = userMapper.updateByPrimaryKeySelective(user);
        //如果number大于0,就证明该数据修改成功
        if (number>0) {
            //此时就需要把数据同步到缓存中去
            List<User> users = redisTemplate.opsForList().range("users", 0, -1);
            for (int i = 0; i < users.size(); i++) {
                if (user.getUid().equals(users.get(i).getUid())){
                    redisTemplate.opsForList().set("users",i,user);
                }
            }
        }
        return number;
    }

    @Override
    public int insertUser(User user) {
        //先把数据插入到数据库中
        int number = userMapper.insert(user);
        //如果number大于0,就证明该数据插入成功
        if (number>0) {
            //此时就需要把数据同步到缓存中去
            //注意:如果你直接把user对象插入到缓存中key为users里面的话,那么这条数据是没有uid的
            //那么没有uid的user数据,在进行跟uid有关的操作过程中,会报错的,所以我们得想办法得到
            //插入到数据库中后得到的uid
            redisTemplate.opsForList().leftPush("users",user);
        }
        return number;
    }

}
